home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 262_01.zip / CMENUC.C < prev    next >
C/C++ Source or Header  |  1993-04-14  |  6KB  |  220 lines

  1. /********************************************************
  2.  *                      C M E N U                       *
  3.  *                                                      *
  4.  *         A compiler for menu driven programs          *
  5.  *                   by Robert Ramey                    *
  6.  ********************************************************/
  7. #include "stdio.h"
  8. #include "symdef.h"
  9.  
  10. #define QUOTE   '\''    /* character used for quote by assembler */
  11. #define MAXDEPTH 10 /* Maximum number of digits in menu code */
  12. #define MAXLINE 128 /* Maximum length of any line in menu */
  13. #define MAXMENUS 50 /* Maximum number of menus */
  14. #define MAXSIZE 11  /* Space reserved for a symbol */
  15.  
  16. SYMBOLTABLE *mtable;    /* Accumulates menus */
  17. SYMBOLTABLE *atable;    /* Stores external symbols */
  18.  
  19. typedef struct mline {
  20.     struct mline *link;
  21.     char mtext[2];
  22.     } MLINE;
  23.  
  24.  
  25. char *marray[MAXMENUS];
  26. int mindex;
  27. int strcmp();
  28. char *strmov();
  29.  
  30. main(argc,argv)
  31. int argc;
  32. char *argv[];
  33. {
  34.     moat(2000);
  35.     mtable = symmk(sizeof(MLINE *), MAXMENUS);
  36.     if(!mtable){
  37.         fprintf(stderr, "Not enough memory");
  38.         exit(1);
  39.     }
  40.     load();
  41.     qsort(marray, mindex + 1, strcmp);
  42.     generate(); /* generate c code for menus */
  43. }
  44. load(){
  45.     char line[MAXLINE];
  46.     MLINE *last, *tptr; /* last element allocated in menu list */
  47.     int i, errflag;
  48.     
  49.     errflag = FALSE;
  50.  
  51.     /* load nul symbol corresponding to root menu */
  52.     marray[mindex = 0] = symadd(mtable, "");
  53.     last = NULL;
  54.     while(gets(line)){
  55.         if(isspace(line[0])){
  56.             if(errflag) continue;
  57.             for(i = 1;isspace(line[i]);++i);
  58.             tptr =
  59.             malloc(sizeof(char *) + strlen(line + i) + 1);
  60.             if(last)
  61.                 last->link = tptr;
  62.             else
  63.                 *(MLINE **)
  64.                 symdat(mtable,marray[mindex]) = tptr;
  65.             last = tptr;
  66.             last->link = NULL;
  67.             strmov(last->mtext, line + i);
  68.         }
  69.         else{
  70.             if(symlkup(mtable, line)){
  71.                 fprint(stderr,"%s menu repeated\n");
  72.                 errflag = TRUE;
  73.             }
  74.             else{
  75.                 marray[++mindex] =symadd(mtable, line);
  76.                 last = NULL;
  77.                 errflag = FALSE;
  78.             }
  79.         }
  80.     }
  81. }
  82. generate(){
  83.     MLINE *mptr;
  84.     char sfix[2],c, cbuffer[MAXDEPTH], *current, *next;
  85.     char s1[MAXLINE], s2[MAXSIZE], s3[MAXSIZE];
  86.     int litcount, i;
  87.  
  88.     /* preamble */
  89.     printf("#include menu.h\n");
  90.     printf("extern char hist[];\n");
  91.  
  92.     atable = symmk(0, MAXMENUS * 4);
  93.     if(!atable){
  94.         fprintf(stderr, "Not enough memory");
  95.         exit(1);
  96.     }
  97.     symadd(atable,"menu");
  98.     symadd(atable,"action");
  99.     symadd(atable,"hist");
  100.     i = 0;
  101.     next = marray[mindex];
  102.     do{
  103.         current = next;
  104.         if(mindex){
  105.             next = marray[mindex - 1];
  106.             if(strncmp(next, current, strlen(current) - 1))
  107.                 printf("menu %s has no father\n"
  108.                     ,current);
  109.         }
  110.  
  111.         /* generate external statements for action routines */
  112.         c = ' ';
  113.         mptr = *(MLINE **)symdat(mtable, current);
  114.         while(mptr = mptr->link){
  115.             /* check for continuation lines */
  116.             if(mptr->mtext[1] != '.') continue;
  117.             if(1 < mksym(mptr->mtext, s1, s2, s3)
  118.             && !symlkup(atable, s2)){
  119.                 if(c == ' ')
  120.                     printf("extern int");
  121.                 putchar(c);
  122.                 printf("%s()",s2);
  123.                 symadd(atable, s2);
  124.                 c = ',';
  125.             }
  126.         }
  127.         if(c != ' ')
  128.             printf(";\n");
  129.  
  130.         /* generate menu data structures */
  131.         mptr = *(MLINE **)symdat(mtable, current);
  132.         if(mindex)
  133.             printf("static ");
  134.         printf("struct {\n");
  135.         printf("\tchar *question = \"");
  136.         for(;;){
  137.             printf("%s",mptr->mtext);
  138.             mptr = mptr->link;
  139.             if(mptr->mtext[1] != '.')
  140.                 printf("\\n\\\n");
  141.             else{
  142.                 printf("\";\n");
  143.                 break;
  144.             }
  145.         }
  146.         printf("\tMLINE m[] = ");
  147.         c = '{';
  148.         do{
  149.             switch(mksym(mptr->mtext,s1,s2,s3)){
  150.             case 3:
  151.             case 2:
  152.                 printf("%c\n\t\t{\"%s\",%s,%s}"
  153.                 , c, s1, s2, s3);
  154.                 break;
  155.             case 1:
  156.                 printf("%c\n\t\t{\"%s\"",c,s1);
  157.                 sfix[0] = mptr->mtext[0];
  158.                 sfix[1] = NULL;
  159.                 strmov(strmov(cbuffer, current),sfix);
  160.                 if(symlkup(mtable, cbuffer)){
  161.                     printf(",menu,&m%s}",cbuffer);
  162.                 }
  163.                 else
  164.                     printf(",action,&hist}");
  165.             }
  166.             c = ',';
  167.         }
  168.         while(mptr = mptr->link);
  169.         printf(";\n\t};\n\tint eos = NULL;\n");
  170.         printf("} m%s;\n", current);
  171.     }
  172.     while(mindex--);
  173. }
  174. /************************************************************
  175. mksym - separate action routine name and argument.
  176. *************************************************************/
  177. int
  178. mksym(instring, sa)
  179. char *instring, *sa;
  180. {
  181.     char c, *cptr,*s, **sb, tstring[MAXSIZE];
  182.     int i, j;
  183.  
  184.     sb = &sa;
  185.     s = *sb++;
  186.     cptr = ";()";
  187.     c = *cptr++;
  188.     i = 0;
  189.     while(i < 3){
  190.         if(*instring == NULL){
  191.             ++i;
  192.             *s = NULL;
  193.             break;
  194.         }
  195.         if(*instring == c){
  196.             ++i;
  197.             *s = NULL;
  198.             s = *sb++;
  199.             c = *cptr++;
  200.             ++instring;
  201.         }
  202.         else
  203.             *s++ = *instring++;
  204.     }
  205.     for(j = i;j < 3;++j)
  206.         *sb++ = "0";
  207.     sb = &sa + 1;
  208.     for(j = 1;j < 3;++j, ++sb){
  209.         if(**sb == NULL)
  210.             strmov(*sb, "0");
  211.     }
  212.     sb = &sa + 2;
  213.     if(isalpha(**sb)){
  214.         strmov(strmov(tstring,"&"),*sb);
  215.         strmov(*sb, tstring);
  216.         *sb = tstring;
  217.     }
  218.     return i;
  219. }
  220.